#pragma once
#include <WinSock2.h>
#include <vector>
#include <map>
#include <memory>
#include <string>
#include <deque>
#include "base.h"
#include "NetBuf.h"

using std::tr1::shared_ptr;

class Packet;
class NetServer;
class NetConnection;


#define INVAILD_CONID 0

struct MY_OVERLAPPED : public WSAOVERLAPPED
{
	NetConnection* pConnection;
	int			nOpt;
};

class NetConnection
{
public:
	enum
	{
		State_None,
		State_Conneting,
		State_Connected,
		State_Stopping,
		State_Stopped,
	};
	NetConnection(ConectionID _nID);
	virtual ~NetConnection();

	virtual ServerID GetServerID()const {return 0;}
	int    GetConnectID()const {return m_nID;}
	SOCKET GetSocket()const{return m_socket;}
	int    GetState()const {return m_state;}
	void   SetState(int _state){m_state = _state;}

	bool Disconnect();
	bool SendPack(Packet* pPakcet);


	//Packet Opt
	void PushBackPacket(Packet* pPacket);
	Packet* PopPacket();
	//Compelte Callback
	bool Receive_Complete(int transBytes);
	bool Send_Complete(int transBytes);
	virtual void Stop_Complete();
	virtual void Stop_Fail();

protected:
	bool _AppendReceive();
	bool _Disconnect();
	bool _AppendSend();

	SOCKET        m_socket;

	int			  m_state;
	bool		  m_bPendingSend;
	int           m_nID;

	MY_OVERLAPPED m_otherOVERLAPPED;
	MY_OVERLAPPED m_SendOVERLAPPED;
	MY_OVERLAPPED m_RecvOVERLAPPED;

	NetBuffer     m_sendBuffer;
	NetBuffer     m_receiveBuffer;
	char		  m_AcceptBuf[1024];

	HANDLE        m_IOCP;
};
class ServerConnection : public NetConnection
{
public:
	ServerConnection(ServerID id,ConectionID _nConID);
	//
	ServerID GetServerID()const {return m_serverID;}

	bool Accept(HANDLE IOCP,SOCKET _listen);
	bool Accept_Complete();

	virtual void Stop_Complete();
	virtual void Stop_Fail();

private:
	ServerID m_serverID;

};
class ClinetConnection : public NetConnection
{
public:
	ClinetConnection(int _nID);
	bool Connect(HANDLE IOCP,const char* pIP,int nPort);
	bool Asyn_Connect(HANDLE IOCP,const char* pIP,int nPort);
	bool Connect_Complete(int error);
	void Connect_Fail();
private:
};